import { WeatherService } from './weather.service';
import {
  BadRequestException,
  Body,
  Controller,
  Get,
  Header,
  HttpException,
  HttpStatus,
  Param,
  Query,
  StreamableFile,
  Version,
  VERSION_NEUTRAL,
} from '@nestjs/common';
import pinyin from 'pinyin';
import { HttpService } from '@nestjs/axios';
import { firstValueFrom } from 'rxjs';
import { Logger } from 'src/common/logger/logger';
import { createReadStream, createWriteStream, WriteStream } from 'node:fs';
import { join } from 'node:path';

const APPKEY = '0c51892228814dd7b8ca1b88723b0363';

@Controller({
  path: 'weather',
  version: '1',
})
export class WeatherController {
  constructor(
    private readonly weatherService: WeatherService,
    private readonly httpService: HttpService,
    private readonly logger: Logger,
  ) {}

  /**
   * 将中文转换为拼音（默认版本v1）
   * url http://127.0.0.1:3333/api/weather/pinyin?text=上海
   * url http://127.0.0.1:3333/api/v1/weather/pinyin?text=上海
   * @param text 中文
   * @returns 拼音字符串
   */
  @Get('pinyin')
  @Version([VERSION_NEUTRAL, '1']) // 版本兼容 v1 和 默认版本
  defaultPinyin(@Query('text') text: string) {
    const pinyinWord = pinyin(text, { style: pinyin.MODE_NORMAL });
    return pinyinWord.join('');
  }

  // 根据地址下载文档文件
  @Get('download-file')
  async downloadFile(@Body() body: any) {
    try {
      const { url } = body;
      const file = await firstValueFrom(
        this.httpService.get(url, {
          responseType: 'stream',
        }),
      );

      const stream: WriteStream = createWriteStream(join('/public', body.key));
      file.data.pipe(stream);
    } catch (error) {
      this.logger.log(error, '------error-----');
      throw new HttpException(
        { error: '下载文件失败' },
        HttpStatus.BAD_REQUEST,
      );
    }
  }

  @Get('get-package')
  @Header('Content-Type', 'application/json')
  @Header('Content-Disposition', 'attachment; filename="package.json"')
  getFileUsingStaticValues(): StreamableFile {
    const file = createReadStream(join(process.cwd(), 'package.json'));
    // 直接返回 StreamableFile 实例 默认的内容类型（即 HTTP 响应头 Content-Type 的值）是 application/octet-stream
    return new StreamableFile(file);

    //  或者
    //   return new StreamableFile(file, {
    //   type: 'application/json',
    //   disposition: 'attachment; filename="package.json"',
    //   // 如果你想将 Content-Length 值定义为文件长度以外的其他值：
    //   // length: 123,
    // });
  }

  /**
   * 将中文转换为拼音
   * url http://127.0.0.1:3333/api/v2/weather/pinyin?text=上海
   * @param text 中文
   * @returns 拼音
   */
  @Version('2')
  @Get('pinyin')
  pinyinV2(@Query('text') text: string) {
    const pinyinWord = pinyin(text, { style: pinyin.MODE_NORMAL });
    return pinyinWord;
  }

  /**
   * 根据城市名称获取天气信息
   * url http://127.0.0.1:3333/api/weather/get-weather-by-city/上海
   * @param city 城市名称
   * @returns 天气信息
   */
  @Get('get-weather-by-city/:city')
  async weather(@Param('city') city: string) {
    const cityPinyin = pinyin(city, { style: pinyin.STYLE_NORMAL }).join('');
    try {
      const res = await firstValueFrom(
        this.httpService.get(
          `https://geoapi.qweather.com/v2/city/lookup?location=${cityPinyin}&key=${APPKEY}`,
        ),
      );

      const location = res.data?.['location']?.[0];
      if (!location) {
        throw new BadRequestException('没有对应的城市信息');
      }

      const { data: weatherData }: any = await firstValueFrom(
        this.httpService.get(
          `https://devapi.qweather.com/v7/weather/7d?location=${location.id}&key=${APPKEY}`,
        ),
      );
      return weatherData;
    } catch (error) {
      this.logger.log(error, '------error-----');
      throw new BadRequestException('获取城市天气失败');
    }
  }
}
